<template>
  <div>
    <el-autocomplete
      v-model="searchText"
      popper-class="my-autocomplete"
      style="width: 100%"
      class="inline-input"
      :fetch-suggestions="querySearch"
      placeholder="搜索地址"
      :trigger-on-focus="false"
      @select="onSelectAddr"
    >
      <template slot-scope="{ item }">
        <div class="name">{{ item.value }}</div>
        <span class="addr">{{ item.address }}</span>
      </template>
    </el-autocomplete>
    <div id="container" style="width: 100%;height: 240px;" />
  </div>
</template>

<script>
export default {
  name: 'QqMap',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    readonly: {
      type: Boolean,
      default: false
    },
    itemfield: {
      type: Object,
      default: function() {
        return {}
      }
    },
    form: {
      type: Object,
      default: function() {
        return {}
      }
    },
    value: {
      type: [Number, Object, String],
      default: function() {
        return {}
      }
    },
    query: {
      type: Object,
      default: function() {
        return {
          query: '',
          queryColumn: '',
          order: '',
          column: '',
          curPage: 1,
          pageSize: 200
        }
      }
    }
  },
  data() {
    return {
      modelValue: this.value,
      map: null, // qq map
      mapInfo: {
        lat: 0,
        lng: 0,
        city: '',
        province: '',
        address: ''
      }, // map infos
      localForm: {},
      options: [],
      searchText: '',
      isInit: true,
      marker: null,
      markers: [],
      geocoder: null,
      center: {},
      searchService: null,
      listQuery: {
        query: '',
        queryColumn: '',
        order: '',
        column: '',
        curPage: 1,
        pageSize: 200
      },
      listData: {
        current: 0,
        pages: 0,
        searchCount: true,
        size: 20,
        total: 0,
        records: []
      }
    }
  },
  computed: {
    itemid() {
      return this.$route.params.id
    },
    cname() {
      return this.$route.params.cname
    }
  },
  watch: {
    value(newValues) {
      this.modelValue = newValues

      // 如果没地址，表示是从省市控件选出来的，就触发一次查找
      if (!newValues.address) {
        this.provinceCityChange(newValues)
      }
    },
    query(newValues) {
      this.listQuery = newValues
    },
    form(newValues) {
      this.localForm = Object.assign({}, newValues)
      this.fetchData()
    },
    itemfield(newValues) {
      this.fetchData()
    }
  },
  mounted() {
    console.log(this.itemfield)
    console.log(this.form)
    console.log(this.readonly)
    console.log(this.disabled)
    this.listQuery = this.query
    this.localForm = Object.assign({}, this.form)
    this.fetchData()
  },
  methods: {
    fetchData() {
      const info = this.itemfield.data
      this.mapInfo.city = this.localForm[info.city.name]
      this.mapInfo.province = this.localForm[info.province.name]
      this.mapInfo.lng = this.localForm[info.lng.name]
      this.mapInfo.lat = this.localForm[info.lat.name]
      this.mapInfo.address = this.localForm[info.address.name]
      if (this.mapInfo.lat && this.mapInfo.lng) {
        this.initMap(this.mapInfo.lat, this.mapInfo.lng)
      } else {
        this.initMap()
      }
    },
    initMap(lat, lng) {
      console.log('initMap', lat, lng)
      const qq = window.qq
      let map = this.map
      if (lat) {
        this.center = new qq.maps.LatLng(lat, lng)// 设置中心点坐标
      } else {
        this.center = new qq.maps.LatLng(36.061864477054485, 120.38505479693413)// 设置中心点坐标
      }
      // 初始化地图
      if (!this.map) {
        this.map = map = new qq.maps.Map('container', {
          center: this.center,
          zoom: 13
        })
      } else {
        this.map.setCenter(this.center)
      }

      if (lat) {
        this.createMarker(lat, lng, true)
      }

      qq.maps.event.addListener(
        map,
        'click',
        (event) => {
          const lat = event.latLng.getLat()
          const lng = event.latLng.getLng()
          this.mapInfo.lat = lat
          this.mapInfo.lng = lng
          this.createMarker(lat, lng, false)
        }
      )
    },
    createMarker(lat, lng, isInit) {
      const that = this
      const qq = window.qq
      const map = this.map

      if (!map) {
        return
      }

      this.isInit = isInit

      // console.log('createMarker',lat, lng, new TMap.LatLng(lat, lng))
      const center = new qq.maps.LatLng(lat, lng)

      // 创建一个Marker
      if (this.marker !== null) {
        this.marker.setMap(null)
        this.marker = null
      }

      this.marker = new qq.maps.Marker({
        // 设置Marker的位置坐标
        position: center,
        // 设置显示Marker的地图
        map: map
      })
      if (this.geocoder === null) {
        this.geocoder = new qq.maps.Geocoder({
          complete: function(result) {
            if (!that.isInit) {
              that.mapInfo.address = result.detail.address
              that.mapInfo.province = result.detail.addressComponents.province
              that.mapInfo.city = result.detail.addressComponents.city
              that.$emit('select', {
                info: that.mapInfo,
                item: that.itemfield
              })
            }
          }
        })
      }

      var coord = new qq.maps.LatLng(lat, lng)
      this.geocoder.getAddress(coord)
    },
    removeMarker() {
      if (this.marker) {
        this.marker.setMap(null)
        this.marker = null
      }
    },
    clearMarks() {
      // 清除所有标记
      var mark
      // eslint-disable-next-line no-cond-assign
      while (mark = this.markers.pop()) {
        mark.setMap(null)
      }
    },
    provinceCityChange({ province, city, address }, cb) {
      // console.log('provinceCityChange', province, city, address)
      const thiz = this
      const qq = window.qq
      const map = this.map
      this.clearMarks()
      if (!province && !city) {
        if (cb) this.$message.error('请先选择城市')
        return
      }
      const location = (city !== '市辖区' && city !== '省直辖县级行政区划' ? province + city : province)
      this.searchService = new qq.maps.SearchService({
        // 检索成功的回调函数
        complete: function(results) {
          // 设置回调函数参数
          var pois = results.detail.pois
          var infoWin = new qq.maps.InfoWindow({
            map: map
          })
          var latlngBounds = new qq.maps.LatLngBounds()
          thiz.options = []
          if (!pois) {
            console.log('搜索失败')
            return
          }
          for (var i = 0; i < pois.length; i++) {
            var poi = pois[i]
            // 添加数据到下拉菜单
            thiz.options.push({
              value: poi.name,
              address: poi.address,
              lat: poi.latLng.getLat(),
              lng: poi.latLng.getLng()
            })

            // 扩展边界范围，用来包含搜索到的Poi点
            latlngBounds.extend(poi.latLng);

            (function(n) {
              var marker = new qq.maps.Marker({
                map: map
              })
              marker.setPosition(pois[n].latLng)

              marker.setTitle(poi.name)
              thiz.markers.push(marker)

              qq.maps.event.addListener(marker, 'click', function() {
                qq.maps.selInfo = () => {
                  const lat = pois[n].latLng.getLat()
                  const lng = pois[n].latLng.getLng()
                  thiz.mapInfo.lat = lat
                  thiz.mapInfo.lng = lng
                  thiz.mapInfo.address = pois[n].address
                  thiz.$emit('select', {
                    info: thiz.mapInfo,
                    item: thiz.itemfield
                  })
                }
                infoWin.open()
                infoWin.setContent(`<div style="width:280px;height:110px;">
                  <div>${pois[n].name}</div><div class="addr">${pois[n].address}</div>
                  <button type="button" onclick="qq.maps.selInfo()">使用</button>
                  </div>`)
                infoWin.setPosition(pois[n].latLng)
              })
            })(i)
          }
          // 调整地图视野
          map.fitBounds(latlngBounds)
          if (cb) cb(thiz.options)
        },
        // 若服务请求失败，则运行以下函数
        error: function(e) {
          console.log('qqMap 出错啦！', e)
        }
      })
      this.$nextTick(() => {
        // 根据输入的城市设置搜索范围
        this.searchService.setLocation(location)
        // 设置搜索页码
        this.searchService.setPageIndex(0)
        // 设置每页的结果数
        this.searchService.setPageCapacity(10)
        this.searchService.search(address || location)
      })
    },
    onSelectAddr(env) {
      // console.log('onSelectAddr', env)
      this.mapInfo.lat = env.lat
      this.mapInfo.lng = env.lng
      this.mapInfo.address = env.address
      this.clearMarks()
      this.initMap(env.lat, env.lng)
      this.$emit('select', {
        info: this.mapInfo,
        item: this.itemfield
      })
    },
    querySearch(env, cb) {
      // console.log('querySearch', env)
      this.provinceCityChange({ province: this.modelValue.province, city: this.modelValue.city, address: env }, cb)
    }
  }
}
</script>

<style>
.name {
  text-overflow: ellipsis;
  overflow: hidden;
}
.addr {
  font-size: 12px;
  color: #b4b4b4;
}
.my-autocomplete li .highlighted{
  color: #ddd;
}
.my-autocomplete li {
  line-height: normal;
  padding: 7px;
}
</style>

